﻿namespace WasiewiczHomepage.Repositories
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;

    /// <summary>
    /// Repository for entity models.
    /// </summary>
    /// <typeparam name="TEntity">The type of the entity.</typeparam>
    public interface IRepository<TEntity> where TEntity : class
    {
        /// <summary>
        /// Gets the specified identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>Gets the specified entity.</returns>
        TEntity Get(int id);

        /// <summary>
        /// Exists the specified identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>True, if specified entity exist.</returns>
        bool Exists(int id);

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Delete(TEntity entity);

        /// <summary>
        /// Deletes multiple entities.
        /// </summary>
        /// <param name="entities">Entities to delete.</param>
        void Delete(IEnumerable<TEntity> entities);

        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Update(TEntity entity);

        /// <summary>
        /// Creates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Create(TEntity entity);

        /// <summary>
        /// Creates the or update.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void CreateOrUpdate(TEntity entity);

        /// <summary>
        /// Gets all entities.
        /// </summary>
        /// <returns>Collection of entities.</returns>
        IEnumerable<TEntity> GetAll();

        /// <summary>
        /// Fetches the specified predicate.
        /// </summary>
        /// <param name="predicate">The predicate.</param>
        /// <returns>Collecton of entities.</returns>
        IEnumerable<TEntity> Fetch(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Gets entity as queryable.
        /// </summary>
        /// <returns></returns>
        IQueryable<TEntity> AsQuerable();

        /// <summary>
        /// Saves current operations.
        /// </summary>
        void Save();

        /// <summary>
        /// Evicts the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Evict(TEntity entity);

        /// <summary>
        /// Dynamics the instance.
        /// </summary>
        /// <returns>TEntity.</returns>
        TEntity DynamicInstance();
    }
}
